﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using BasicFramework.Components;
using BasicFramework.Entities;
using BasicFramework.Helper;

namespace BasicFramework.Factory
{
    public sealed class ComponentFactory : Factory
    {
        public static Component Create(Type type, IEntity owner, bool overwrite, params object[] parameters)
        {
            Logger.Info("Creating " + type.Name + " component");
            // Get the Constructor
            ConstructorInfo bestMatch = GetBestMatchingConstructor(type, parameters);

            object obj = null;

            try
            {
                obj = bestMatch.Invoke(parameters);
            }
            catch (TargetParameterCountException tpce)
            {
                throw tpce;
            }

            Component component = obj as Component;

            // Set correct Owner
            component.Owner = owner;
            owner.Add(component, overwrite);

            Logger.Info("Creating " + component.GetType().Name + " component successful");

            return obj as Component;
        }

        public static T Create<T>(IEntity owner) where T : Component
        {
            return Create<T>(owner, new object[] { });
        }

        public static T Create<T>(IEntity owner, params object[] parameters) where T : Component
        {
            return Create<T>(owner, false, parameters);
        }

        public static T Create<T>(IEntity owner, bool overwrite, params object[] parameters) where T : Component
        {
            Logger.Info("Creating " + typeof(T).Name + " component");

            ConstructorInfo bestMatch = GetBestMatchingConstructor(typeof(T), parameters);

            object obj = null;

            try
            {
                obj = bestMatch.Invoke(parameters);
            }
            catch (TargetParameterCountException tpce)
            {
                throw tpce;
            }

            Component component = obj as Component;

            component.Owner = owner;
            owner.Add(component, overwrite);

            Logger.Info("Creating " + component.GetType().Name + " component successful");


            return obj as T;
        }
    }
}
